#ifndef _ASSERT_H_
#define _ASSERT_H_

#include <iostream>

using namespace std;

inline void __assert( const char *_fname, int _ln, const char * _msg)
{
	//TODO Make true assert
	cout << "Assertion failed in file '" << _fname << "'(" << _ln << ") : " << _msg << endl;
	__asm int 3;
}

#ifdef assert
#undef assert
#endif

#ifdef massert
#undef massert
#endif

#ifdef bounds
#undef bounds
#endif

inline void __stacktrace_print()
{
	cout << "ST:" << endl;
}

#ifndef _DEBUG
#define assert(_e)		((void)0)
#define massert(_e,_m)	((void)0)
#define bounds(_i,_n)	((void)0)
#else

/* standard assert macro */
#define assert(_e) \
	{if(_e) (void)0; else{ \
	__stacktrace_print(); \
	__assert(__FILE__, __LINE__, #_e);}}

/* an assert variant that prints out a user supplied message  */
#define massert(_e, _m) \
	{if(_e) (void)0; else{ \
	__stacktrace_print(); \
	__assert(__FILE__, __LINE__, _m);}}

/* an assert variant that checks for array-out-of-bounds */
#define bounds(_i, _n) \
	(((unsigned)(_i)<(_n))? (_i) : \
	( __stacktrace_print(), \
	__assert(__FILE__, __LINE__, \
	"index '" #_i "' out of bounds '" #_n "'"), 0))

#endif

#endif